package com.cmol.net;

import android.util.Log;

import com.cmol.data.GlobalData;
import com.cmol.data.Host;

import org.json.JSONObject;

import java.io.IOException;
import java.net.Proxy;
import java.util.concurrent.TimeUnit;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.ResponseBody;

/**
 * 网络通信模块
 *
 * @author 邢文成
 */
public abstract class Network {
    /**
     * 请求报文
     */
    private JSONObject jsonObject;
    /**
     * okhttp通信
     */
    private OkHttpClient okHttpClient;

    /**
     * 通信主函数
     *
     * @param jsonObject 请求报文
     * @param location   url接口
     */
    public Network(JSONObject jsonObject, String location) {
        this.jsonObject = jsonObject;
        okHttpClient = new OkHttpClient.Builder()
                .connectTimeout(10, TimeUnit.SECONDS)
                .readTimeout(10, TimeUnit.SECONDS)
                .writeTimeout(10, TimeUnit.SECONDS)
                .proxy(Proxy.NO_PROXY)
                .build();
        MediaType mediaType = MediaType.parse("application/json;charset=utf-8");
        RequestBody requestBody = RequestBody.create(mediaType, "" + jsonObject.toString());
        if (GlobalData.getUserToken().length() != 0) {
            Request request = new Request.Builder()
                    .url(Host.host + location)
                    .addHeader("Authorization", GlobalData.getUserToken())
                    .post(requestBody)
                    .build();

            Log.e("request", request.toString());
            Call call = okHttpClient.newCall(request);

            /**
             * 异步响应
             */
            call.enqueue(new Callback() {
                /**
                 * Called when the request could not be executed due to cancellation, a connectivity problem or
                 * timeout. Because networks can fail during an exchange, it is possible that the remote server
                 * accepted the request before the failure.
                 *连接失败
                 *
                 * @param call
                 * @param e
                 */
                @Override
                public void onFailure(Call call, IOException e) {
                    failureWarn();
                }


                /**
                 * Called when the HTTP response was successfully returned by the remote server. The callback may
                 * proceed to read the response body with . The response is still live until
                 * its response body is {@linkplain ResponseBody closed}. The recipient of the callback may
                 * consume the response body on another thread.
                 *
                 * <p>Note that transport-layer success (receiving a HTTP response code, headers and body) does
                 * not necessarily indicate application-layer success: {@code response} may still indicate an
                 * unhappy HTTP response code like 404 or 500.
                 *
                 * @param call
                 * @param response
                 */
                @Override
                public void onResponse(Call call, Response response) throws IOException {
                    if (response.code() == 200) {
                        process(call, response);
                    }
                }
            });
        }
    }


    /**
     * @param call
     * @param response 响应报文
     *                 200ok 处理响应
     */
    protected abstract void process(Call call, Response response) throws IOException;

    /**
     * 链接终端或失败
     * 显示网络异常提示
     */
    protected abstract void failureWarn();


}